<?php
/**
 * Created by PhpStorm.
 * User: lzhy@lzhy.me
 * Date: 2019/4/12 0012
 * Time: 16:59
 */
namespace app\admin\event;

use think\Db;
use think\facade\Env;
use think\facade\Request;

class Dt
{
    private static $table;
    private static $field = '*';
    private static $search_field;
    private static $order;
    private static $format;
    private static $tableAlias;
    private static $joinTables = [];

    /**
     * 设置参与搜索的字段
     * @param $field
     * @return $this
     */
    public function searchField($field)
    {
        if(is_array($field)){
            $field = join('|',$field);
        }
        if(is_string($field)){
            $field = join('|',explode(',',$field));
        }
        self::$search_field = $field;
        return $this;
    }

    /**
     * 设置查询字段
     * @param string $field
     * @return $this
     */
    public function field($field = '*')
    {
        self::$field = $field;
        return $this;
    }

    /**
     * @param $table //eg:单表：user;多表：user#a,user_info#b#a.id=b.uid#left
     * @return $this
     * @throws \Exception
     */
    public function table($table)
    {
        if(false !== strpos($table,',')){
            $tArr = explode(',',$table);
            self::$table = array_shift($tArr);
            if(false !== strpos(self::$table,'#')){
                $_sTArr = explode('#',self::$table);
                self::$table = $_sTArr[0];
                self::$tableAlias = $_sTArr[1];
            }

            if($tArr){
                $_dbPrefix = Env::get('DB_PREFIX');
                $_join = [];
                foreach ($tArr as $k => $v){
                    $_join[$k] = $v;
                    if(false !== strpos($v,'#')){
                        $_sTArr = explode('#',$v);
                        if(count($_sTArr) < 3){
                            throw new \Exception('配置传入错误',301);
                        }
                        if(strpos($_sTArr[0],$_dbPrefix) !== 0){
                            $_sTArr[0] = $_dbPrefix.$_sTArr[0];
                        }
                        $_join[$k] = [
                            $_sTArr[0].' as '.$_sTArr[1].' on '.$_sTArr[2],
                            $_sTArr[3] ?? 'INNER'
                        ];
                    }
                }
                self::$joinTables = $_join;
            }
            return $this;
        }

        self::$table = $table;
        return $this;
    }

    /**
     * 数据格式化
     * @param array $format
     * @return $this
     */
    public function format($format = [])
    {
        self::$format = $format;
        return $this;
    }

    /**
     * 排序
     * @param $order
     * @return $this
     */
    public function order($order)
    {
        if($order){
            self::$order = $order;
        }
        return $this;
    }

    /**
     * 获取
     * @param array $where
     * @return array
     * @throws \Exception
     */
    public function fetch($where = [])
    {
        if(empty(self::$table)){
            throw new \Exception('表名必须输入',300);
        }

        $params = $this->requestParams();
        $order  = $params['columns'][$params['order'][0]['column']]['data'].' '.$params['order'][0]['dir'];
        if(self::$order){
            $order = self::$order;
        }
        if(@$params['search']['value'] && self::$search_field){
            $where = array_merge([[
                self::$search_field,
                'like',
                '%'.trim($params['search']['value'])
            ]],$where);
        }

        $list = $this->mHandle()
            ->field(self::$field)
            ->where($where)
            ->order($order)
            ->limit($params['start'],$params['length'])
            ->select();

        $total = $this->mHandle()->count();
        $filterTotal = $this->mHandle()->where($where)->count();

        $data = [
            'data' => $this->_dataFormat($list),
            'draw' => $params['draw'],
            'recordsTotal'    => $total,
            'recordsFiltered' => $filterTotal
        ];

        return $data;
    }

    /**
     * 数据格式化
     * @param $list
     * @return mixed
     */
    private function _dataFormat($list)
    {
        if(self::$format){
            $_fKeys = array_keys(self::$format);
            foreach ($list as $k => &$v){
                if($_fKeys){
                    foreach ($_fKeys as $_fv){
                        $_fT = @self::$format[$_fv];
                        if($_fT){
                            $v[$_fv.'_raw'] = $v[$_fv];
                            if(is_array($_fT)){
                                $v[$_fv] = isset($_fT[$v[$_fv]])?$_fT[$v[$_fv]]:$v[$_fv];
                            }
                            if(is_object($_fT)){
                                $v[$_fv] = @$_fT($v[$_fv],$v,$list);
                            }
                        }
                    }
                }
            }
        }

        return $list;
    }

    /**
     * 获取数据操作句柄
     * @return \Model|\Think\Model
     */
    private function mHandle()
    {
        $_mTable = Db::name(self::$table);
        if(self::$tableAlias){
            $_mTable = $_mTable->alias(self::$tableAlias);
        }
        if(self::$joinTables){
            foreach (self::$joinTables as $v){
                $_mTable = $_mTable->join($v[0],$v[1]);
            }
        }

        return $_mTable;
    }

    /**
     * 参数
     * @return array
     */
    private function requestParams()
    {
        $draw   = Request::param('draw',1);
        $start  = Request::param('start',0);
        $length = Request::param('length',10);
        $search = Request::param('search','');
        $order  = Request::param('order');
        $columns = Request::param('columns');


        return [
            'draw'   => $draw,
            'start'  => $start,
            'length' => $length,
            'search' => $search,
            'order'  => $order,
            'columns' => $columns
        ];
    }
}